<?php
namespace app\Utils;

use Exception;
use JsApiPay\JsApiPay;
use WxPayApi;
use WxPayUnifiedOrder;


class WxPayUtil
{
    protected $app_id;
    protected $mch_id;
    protected $key;
    protected $secret;
    protected $out_trade_no;
    protected $body;
    protected $notify_url;
    protected $total_fee;
    protected $type;
    function __construct($type, $app_id, $secret, $mch_id, $key,$out_trade_no,$body,$total_fee,$notify_url) {
        $this->app_id       = $app_id;
        $this->secret       = $secret;
        $this->mch_id       = $mch_id;
        $this->key          = $key;
        $this->out_trade_no = $out_trade_no;
        $this->body         = $body;
        $this->notify_url   = $notify_url;
        $this->total_fee    = $total_fee;
        $this->type         = $type;
    }

    /**
     * 统一下单接口
     * @return mixed
     */
    public function payOrder()
    {
        try{
            require_once "../extend/wxpaysdk/WxPay.Config.php";
            require_once "../extend/wxpaysdk/WxPay.JsApiPay.php";
            //微信支付参数
            $config = new \WxPayConfig();
            $config->SetAppId($this->app_id);
            $config->SetMerchantId($this->mch_id);
            $config->SetAppSecret($this->secret);
            $config->SetKey($this->key);
            $config->SetNotifyUrl($this->notify_url);

            $tools = new \JsApiPay();
            //统一下单
            $input = new WxPayUnifiedOrder();
            $input->SetBody($this->body);
            //$input->SetAttach("");//自定义数据
            $input->SetOut_trade_no($this->out_trade_no);
            $input->SetTotal_fee($this->total_fee);
            $input->SetTime_start(date("YmdHis"));
            $input->SetTime_expire(date("YmdHis", time() + 600));
            $input->SetNotify_url($this->notify_url);
            $input->SetTrade_type($this->type);
            if($this->type == "JSAPI"){
                $openId = $tools->GetOpenid();
                $input->SetOpenid($openId);
            }

            $order = WxPayApi::unifiedOrder($config, $input);
            if($this->type == "JSAPI"){
                $jsApiParameters = $tools->GetJsApiParameters($order);
                return ['code'=>0,'data'=>$jsApiParameters,'msg'=>"创建支付订单成功". PHP_EOL];
            }else{
                if($order['return_code'] == 'SUCCESS'){
                    $arr = [
                        'prepayid'   => $order['prepay_id'], //
                        'appid'      => $order['appid'], //
                        'partnerid'  => $order['mch_id'], //
                        'package'    => 'Sign=WXPay', //
                        'noncestr'   => $order['nonce_str'], //
                    //    'trade_type' => $order['trade_type'],
                        'time_stamp' => time(),
                    ];
                    //签名
                    $sign = $this->getSign($arr,$this->key);
                    $arr['sign'] = $sign;
                    $arr['trade_type'] = $order['trade_type'];
                    return ['code'=>0,'data'=>json_encode($arr),'msg'=>"创建支付订单成功". PHP_EOL];
                }
            }

        } catch(Exception $e) {
            return ['code'=>-1,'data'=>null,'msg'=>"调用失败，". $e->getMessage()];
        }
    }

    function getSign($params,$key){
        ksort($params); //将参数数组按照参数名ASCII码从小到大排序
        foreach ($params as $key => $item) {
           if(!empty($item)){
               $newArr[] = $key.'='.$item; // 整合新的参数数组
           }
        }
        $stringA = implode("&", $newArr); //使用 & 符号连接参数
        $stringSignTemp = $stringA."&key=".$key; //拼接key
        $stringSignTemp = MD5($stringSignTemp); //将字符串进行MD5加密
        $sign = strtoupper($stringSignTemp); //将所有字符转换为大写
        return $sign;
    }


    /**
     * 退款接口
     * @return array
     */
    public function refundOrder()
    {

        try {
            //2. 发起API调用 refund（交易退款）
            $result = "";
            //3. 处理响应或异常
            return ['code'=>0,'data'=>$result,'msg'=>"调用成功". PHP_EOL];
        } catch (Exception $e) {
            return ['code'=>-1,'data'=>null,'msg'=>"调用失败，". $e->getMessage()];
        }

    }

}
